package com.fand.manager.service.impl;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fand.common.exception.BusinessException;
import com.fand.common.util.PageResult;
import com.fand.common.util.PageUtil;
import com.fand.common.util.QueryWrapperUtil;
import com.fand.manager.entity.SysUser;
import com.fand.manager.mapper.SysUserMapper;
import com.fand.manager.model.user.SysUserPostDTO;
import com.fand.manager.model.user.SysUserReturnDTO;
import com.fand.manager.model.user.SysUserSearchDTO;
import com.fand.manager.service.ISysUserService;
import org.springframework.aop.framework.AopContext;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author javaboy
 * @since 2021-06-02
 */
@Service
public class SysUserServiceImpl implements ISysUserService {

    @Resource
    private SysUserMapper         sysUserMapper;
    @Resource
    private BCryptPasswordEncoder passwordEncoder;


    @Transactional
    @Override
    public Boolean saveUser(SysUserPostDTO sysUserPostDTO) {
        if (Objects.isNull(sysUserPostDTO)) {
            throw new BusinessException("用户信息不能为空");
        }
        SysUser sysUser = SysUser.builder().build();
        BeanUtil.copyProperties(sysUserPostDTO, sysUser);
        sysUser.setPassword(passwordEncoder.encode(sysUser.getPassword()));
        int row = sysUserMapper.insert(sysUser);
        if (row == 0) {
            throw new RuntimeException("保存失败");
        }
        return Boolean.TRUE;
    }

    @Cacheable(value = "sys-user")
    @Override
    public SysUserReturnDTO findUser(Long id) {
        if (Objects.isNull(id)) {
            throw new BusinessException("主键不能为空");
        }
        SysUserReturnDTO sysUserReturnDTO = SysUserReturnDTO.builder().build();
        SysUser sysUser = sysUserMapper.selectById(id);
        BeanUtil.copyProperties(sysUser, sysUserReturnDTO);
        return sysUserReturnDTO;
    }

    @CacheEvict(value = "sys-user")
    @Transactional
    @Override
    public Boolean deleteUser(Long id) {
        if (Objects.isNull(id) || id < 1) {
            throw new BusinessException("用户id不能为空");
        }
        int count = sysUserMapper.deleteById(id);
        return Boolean.TRUE;
    }

    @CacheEvict(value = "sys-user", key = "#sysUserPostDTO.id")
    @Transactional
    @Override
    public Boolean updateUser(SysUserPostDTO sysUserPostDTO) {
        if (Objects.isNull(sysUserPostDTO) || Objects.isNull(sysUserPostDTO.getId())) {
            throw new BusinessException("数据异常");
        }
        SysUser sysUser = SysUser.builder().build();
        BeanUtil.copyProperties(sysUserPostDTO, sysUser);
        sysUserMapper.updateById(sysUser);
        return Boolean.TRUE;
    }

    @Override
    public PageResult<List<SysUserReturnDTO>> listUsers(SysUserSearchDTO sysUserSearchDTO) {
        QueryWrapper queryWrapper = QueryWrapperUtil.builder().queryWrapper(new QueryWrapper()).object(sysUserSearchDTO).build().builderQueryParams();
        Page page = PageUtil.page(sysUserSearchDTO);
        PageResult<List<SysUserReturnDTO>> result = PageUtil.resultToClass(this.sysUserMapper.selectPage(page, queryWrapper), SysUserReturnDTO.class);
        result.setData(result.getData().stream().map(sysUserReturnDTO -> {
            sysUserReturnDTO.setCreatedByName(this.getService().findUser(sysUserReturnDTO.getCreatedBy()).getUserName());
            sysUserReturnDTO.setUpdatedByName(this.getService().findUser(sysUserReturnDTO.getUpdatedBy()).getUserName());
            return sysUserReturnDTO;
        }).collect(Collectors.toList()));
        return result;
    }


    @Transactional
    @Override
    public Boolean deleteByIds(List<Long> idList) {
        if (CollUtil.isEmpty(idList)) {
            throw new BusinessException("请选中要删除的行");
        }
        idList.stream().forEach(id -> this.getService().deleteUser(id));
        return Boolean.TRUE;
    }

    @Override
    public SysUser findUserByUserCode(String userCode) {
        if (StrUtil.isEmpty(userCode)) {
            throw new BusinessException("非法参数");
        }
        SysUser sysUser = this.sysUserMapper.selectOne(new QueryWrapper<SysUser>().eq("user_code", userCode));
        if (Objects.isNull(sysUser)) {
            return SysUser.builder().build();
        }
        return sysUser;
    }

    @CacheEvict(value = "sys-user",key = "#sysUserPostDTO.id")
    @Transactional
    @Override
    public Boolean updatePwd(SysUserPostDTO sysUserPostDTO) {
        if (Objects.isNull(sysUserPostDTO.getPassword())) {
            throw new BusinessException("非法参数");
        }
        int row = sysUserMapper.updatePwd(sysUserPostDTO.getId(), passwordEncoder.encode(sysUserPostDTO.getPassword()));
        if (row > 0) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    private SysUserServiceImpl getService() {
        return (SysUserServiceImpl) AopContext.currentProxy();
    }

}
